package com.upb.webserver.company;

import com.upb.webserver.common.exception.WebServerException;
import com.upb.webserver.common.pojo.company.RspCompanyVO;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.common.tools.JsonUtils;
import com.upb.webserver.common.tools.MybatisExampleTools;
import com.upb.webserver.dao.entity.TbCompany;
import com.upb.webserver.dao.entity.TbCompanyExample;
import com.upb.webserver.dao.mapper.TbCompanyMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;

/**
 * branch of developer.
 */
@Slf4j
@Service
public class CompanyService {

    @Autowired
    private TbCompanyMapper tbCompanyMapper;

    /**
     * @param developerId
     * @return
     */
    @Transactional
    public Integer newCompany(int developerId, String companyName) {
        log.info("start exec method [newCompany] success, developerId:{} companyName:{}", developerId, companyName);

        //check companyName
        checkBeforeNewCompanyName(companyName);

        TbCompany tbCompany = new TbCompany();
        tbCompany.setCompanyName(companyName);
        tbCompany.setDeveloperId(developerId);
        tbCompany.setGmtCreate(new Date());
        tbCompany.setGmtModified(new Date());

        tbCompanyMapper.insertSelective(tbCompany);
        log.info("success exec method [newCompany], return:{}", JsonUtils.objToString(tbCompany));
        return tbCompany.getId();
    }

    /**
     * @param companyId
     * @param companyName
     */
    @Transactional
    public void modifyCompanyName(int companyId, String companyName) {
        log.info("start exec method [modifyCompanyName], companyId:{} companyName:{}", companyId, companyName);
        TbCompany tbCompany = verifyCompanyId(companyId);

        if (tbCompany.getCompanyName().equalsIgnoreCase(companyName)) {
            log.info("jump over  exec method [modifyCompanyName],  found companyName:{} by companyId:{}", companyName, companyId);
            return;
        }
        //check companyName
        checkBeforeNewCompanyName(companyName);


        tbCompany.setCompanyName(companyName);
        tbCompany.setGmtModified(new Date());
        tbCompanyMapper.updateByPrimaryKey(tbCompany);
    }


    /**
     * @param companyId
     * @return
     */
    public RspCompanyVO queryCompanyDetail(Integer companyId) {
        log.info("start exec method [queryCompanyDetail]. companyId:{}", companyId);
        TbCompany tbCompany = tbCompanyMapper.selectByPrimaryKey(companyId);
        if (Objects.isNull(tbCompany)) return null;
        RspCompanyVO rspCompanyVO = new RspCompanyVO();
        BeanUtils.copyProperties(tbCompany, rspCompanyVO);
        log.info("start exec method [queryCompanyDetail]. result:{}", JsonUtils.objToString(rspCompanyVO));
        return rspCompanyVO;
    }


    /**
     * @param companyName
     */
    public void checkBeforeNewCompanyName(String companyName) {
        log.info("start exec method [checkBeforeNewCompanyName]. companyName:{}", companyName);

        if (StringUtils.isBlank(companyName)) {
            log.warn("fail exec method[newCompany]. companyName is blank");
            throw new WebServerException(ConstantCode.PARAM_EXCEPTION.msg("companyName is blank"));
        }

        TbCompanyExample example = MybatisExampleTools.initSampleExample(TbCompanyExample.class, new TbCompany(companyName));
        long countByCompanyName = tbCompanyMapper.countByExample(example);
        log.info("companyName:{} ,found company record count:{} by ", countByCompanyName, companyName);
        if (countByCompanyName > 0) {
            log.warn("fail exec method [checkBeforeNewCompanyName]. companyName:{} has bean in use", companyName);
            throw new WebServerException(ConstantCode.COMPANY_NAME_IN_USE);
        }
        log.info("success exec method [checkBeforeNewCompanyName]. companyName:{} is usable", companyName);
    }

    /**
     * @param companyId
     * @return
     */
    public TbCompany verifyCompanyId(int companyId) {
        log.info("start exec method [verifyCompanyId]. companyId:{}", companyId);
        TbCompany tbCompany = tbCompanyMapper.selectByPrimaryKey(companyId);
        if (Objects.isNull(tbCompany)) {
            log.warn("fail exec method [verifyCompanyId]. not found record by companyId{}", companyId);
            throw new WebServerException(ConstantCode.INVALID_ORG_ID);
        }
        log.info("success exec method [verifyCompanyId]. result:{}", JsonUtils.objToString(tbCompany));
        return tbCompany;
    }

    /**
     * @param companyName
     * @return
     */
    public TbCompany queryByCompanyName(String companyName) {
        log.info("start exec method [queryByCompanyName]. companyName:{}", companyName);
        if (StringUtils.isBlank(companyName))
            return null;

        TbCompanyExample example = new TbCompanyExample();
        TbCompanyExample.Criteria criteria = example.createCriteria();
        criteria.andCompanyNameEqualTo(companyName);

        TbCompany tbCompany = tbCompanyMapper.getOneByExample(example).orElse(null);
        log.info("success exec method [queryByCompanyName]. result:{}", JsonUtils.objToString(tbCompany));
        return tbCompany;
    }

    /**
     * @param companyName
     * @return
     */
    public Integer queryIdByName(String companyName) {
        TbCompany tbCompany = queryByCompanyName(companyName);
        if (null == tbCompany)
            return null;

        return tbCompany.getId();
    }
}
